package BandB.Tool.GPhoneManager.TaskManager;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;

import org.dom4j.DocumentException;

import BandB.Tool.GPhoneManager.TaskManager.Util.DataHandler;
import BandB.Tool.GPhoneManager.TaskManager.Util.Utilities;
import BandB.Tool.GPhoneManager.TaskManager.config.XmlManager;
import android.app.ActivityManager;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class ScheduleService extends Service {

	public static final byte[] SyncTerminateBlacklist = new byte[0];
	private static final String TAG = "ScheduleService";
	private long schedule_timespan = 2 * 60 * 60 * 1000;
	private static final long ONE_DAY_TIME = 24 * 60 * 60 * 1000;

	private XmlManager xmlManager;
	private Timer scheduleTimer;
	private static boolean mRequestRestart = true;
	private static int mIsFirstRunning = 0;
	private static boolean isFirstRunning = true;
	private TimerTask scheduleTask = new TimerTask() {
		@Override
		public void run() {
			synchronized (ScheduleService.SyncTerminateBlacklist) {
				Log.e(TAG, "service run...");
				// isRunning = true;
				ArrayList<ApplicationInfo> appInfo = Utilities
						.getRunningAppList(ScheduleService.this);
				int runningAppsCount = appInfo.size();
				if (0 == runningAppsCount) {
					Log.e(TAG, "no running apps.");
				} else {
					try {
						ActivityManager am = (ActivityManager) getSystemService(Service.ACTIVITY_SERVICE);
						DataHandler dataHandler = new DataHandler(
								ScheduleService.this);
						for (ApplicationInfo applicationInfo : appInfo) {
							String pName = applicationInfo.appInfo.packageName;
							if (dataHandler.isBlack(pName)) {
								am.restartPackage(pName);
							}
						}
					} catch (Exception e) {
						// TODO: handle exception
						e.printStackTrace();
					}
				}
				// isRunning = false;
				Log.e(TAG, "service runs out, waiting for the next running.");
			}
		}
	};

	private TimerTask generateTimerTask() {
		return new TimerTask() {
			@Override
			public void run() {
				synchronized (ScheduleService.SyncTerminateBlacklist) {
					Log.e(TAG, "service run...");
					// isRunning = true;
					ArrayList<ApplicationInfo> appInfo = Utilities
							.getRunningAppList(ScheduleService.this);
					int runningAppsCount = appInfo.size();
					if (0 == runningAppsCount) {
						Log.e(TAG, "no running apps.");
					} else {
						try {
							ActivityManager am = (ActivityManager) getSystemService(Service.ACTIVITY_SERVICE);
							DataHandler dataHandler = new DataHandler(
									ScheduleService.this);
							for (ApplicationInfo applicationInfo : appInfo) {
								String pName = applicationInfo.appInfo.packageName;
								if (dataHandler.isBlack(pName)) {
									am.restartPackage(pName);
								}
							}
						} catch (Exception e) {
							// TODO: handle exception
							e.printStackTrace();
						}
					}
					// isRunning = false;
					Log.e(TAG,
							"service runs out, waiting for the next running.");
				}
			}
		};
	}

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		try {
			xmlManager = new XmlManager(this);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Log.e(TAG, "onCreate called");
	}

	/**
	 * read the config.xml file to determine how the service would be running
	 */
	private void resolveConfig() {
		HashMap<String, String> config = xmlManager.readConfig();
		String type = config.get(XmlManager.ELEMENT_TYPE);
		Log.e(TAG, "resolve config type is:" + type);
		String value = config.get(XmlManager.ELEMENT_VALUE);
		if (type.equals(XmlManager.TYPE_TIME_SPAN)) {
			// schedule_timespan =
			String[] timeDesc = value.split(XmlManager.SPLIT);
			Log.e(TAG, "resolve config, get values string:" + value);
			int hours = Integer.parseInt(timeDesc[0]);
			int mins = Integer.parseInt(timeDesc[1]);
			schedule_timespan = hours * 3600 * 1000 + mins * 60 * 1000;

			if (null != scheduleTask) {
				scheduleTask.cancel();
				scheduleTask = generateTimerTask();
			}
			scheduleTimer = new Timer();
			scheduleTimer.schedule(scheduleTask, 1000, schedule_timespan);
		} else {
			String[] timeDesc = value.split(XmlManager.SPLIT);
			Log.e(TAG, "resolve config, get values string:" + value);
			Calendar c = Calendar.getInstance();
			int year = c.get(Calendar.YEAR);
			int month = c.get(Calendar.MONTH);
			int day = c.get(Calendar.DAY_OF_MONTH);
			int hour = Integer.parseInt(timeDesc[0]);
			int min = Integer.parseInt(timeDesc[1]);
			Date date = new Date(year, month, day, hour, min, 0);
			schedule_timespan = ONE_DAY_TIME;

			if (null != scheduleTask) {
				scheduleTask.cancel();
				scheduleTask = generateTimerTask();
			}
			scheduleTimer = new Timer();
			scheduleTimer.schedule(scheduleTask, date, schedule_timespan);
		}
	}

	@Override
	public void onStart(Intent intent, int startId) {
		// TODO Auto-generated method stub

		if (mIsFirstRunning == 0) {
			isFirstRunning = true;
		} else {
			isFirstRunning = false;
		}
		Log.e(TAG, "service start");
		if (mRequestRestart) {
			resolveConfig();
		}
		mIsFirstRunning++;
		super.onStart(intent, startId);
	}

	public static void setRestart(boolean start) {
		mRequestRestart = start;
	}

	public static boolean isFirstRunning() {
		return isFirstRunning;
	}

}
